package com;

import javax.swing.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 游戏计时和流程控制类
 * 
 * <p>该类负责管理游戏的整个生命周期，包括：
 * <ul>
 *   <li>抢地主阶段的倒计时</li>
 *   <li>游戏主流程的回合控制</li>
 *   <li>玩家出牌倒计时</li>
 *   <li>电脑玩家自动出牌</li>
 *   <li>游戏结束判断</li>
 * </ul>
 */
public class GameTimer extends Thread {
    // 时间常量（秒）
    private static final int LANDLORD_SELECTION_TIME = 15;  // 抢地主选择时间
    private static final int PLAYER_TURN_TIME = 30;         // 玩家回合时间
    private static final int COMPUTER_THINK_TIME = 2;        // 电脑思考时间
    
    private GameMain game;          // 游戏主类引用
    private AtomicBoolean running;   // 线程运行标志
    private int currentPhase;        // 当前游戏阶段
    private int currentPlayer;       // 当前玩家索引
    
    // 游戏阶段常量
    private static final int PHASE_INIT = 0;             // 初始化阶段
    private static final int PHASE_LANDLORD_SELECTION = 1; // 抢地主阶段
    private static final int PHASE_GAMEPLAY = 2;          // 游戏主阶段
    
    /**
     * 构造函数
     * @param game 游戏主类实例
     */
    public GameTimer(GameMain game) {
        this.game = game;
        this.running = new AtomicBoolean(true);
        this.currentPhase = PHASE_INIT;
        this.currentPlayer = -1;
    }
    
    /**
     * 停止计时器
     */
    public void stopTimer() {
        running.set(false);
    }
    
    /**
     * 主线程运行方法
     */
    @Override
    public void run() {
        // 游戏主循环
        while (running.get()) {
            switch (currentPhase) {
                case PHASE_INIT:
                    handleInitializationPhase();
                    break;
                    
                case PHASE_LANDLORD_SELECTION:
                    handleLandlordSelectionPhase();
                    break;
                    
                case PHASE_GAMEPLAY:
                    handleGameplayPhase();
                    break;
            }
            
            // 短暂暂停避免CPU占用过高
            sleep(100);
        }
    }
    
    /**
     * 处理游戏初始化阶段
     */
    private void handleInitializationPhase() {
        // 等待游戏开始
        while (!game.isGameStarted() && running.get()) {
            sleep(500);
        }
        
        // 切换到抢地主阶段
        if (running.get()) {
            currentPhase = PHASE_LANDLORD_SELECTION;
            SwingUtilities.invokeLater(() -> {
                game.startLandownerSelection();
            });
        }
    }
    
    /**
     * 处理抢地主选择阶段
     */
    private void handleLandlordSelectionPhase() {
        // 启动玩家倒计时
        startPlayerTimer(1, LANDLORD_SELECTION_TIME);
        
        // 等待玩家操作或超时
        while (!game.isLandlordDecided() && running.get()) {
            sleep(500);
        }
        
        // 切换到游戏主阶段
        if (running.get()) {
            currentPhase = PHASE_GAMEPLAY;
            SwingUtilities.invokeLater(() -> {
                game.startGame();
            });
        }
    }
    
    /**
     * 处理游戏主阶段
     */
    private void handleGameplayPhase() {
        // 游戏主循环
        while (!game.isGameOver() && running.get()) {
            // 获取当前玩家
            currentPlayer = game.getCurrentPlayer();
            
            // 更新UI显示当前玩家
            SwingUtilities.invokeLater(() -> {
                game.highlightCurrentPlayer(currentPlayer);
            });
            
            // 处理当前玩家回合
            if (currentPlayer == 1) {
                // 玩家回合
                handleHumanPlayerTurn();
            } else {
                // 电脑玩家回合
                handleComputerPlayerTurn(currentPlayer);
            }
            
            // 检查游戏是否结束
            if (game.isGameOver()) {
                handleGameEnd();
                return;
            }
            
            // 切换到下一个玩家
            SwingUtilities.invokeLater(() -> {
                game.nextTurn();
            });
            
            // 短暂暂停
            sleep(500);
        }
    }
    
    /**
     * 处理玩家回合
     */
    private void handleHumanPlayerTurn() {
        // 激活玩家卡牌
        SwingUtilities.invokeLater(() -> {
            game.activatePlayerCards(true);
        });
        
        // 启动玩家倒计时
        startPlayerTimer(1, PLAYER_TURN_TIME);
        
        // 等待玩家操作或超时
        AtomicBoolean playerActed = new AtomicBoolean(false);
        game.setPlayerActionListener(() -> {
            playerActed.set(true);
        });
        
        while (!playerActed.get() && running.get()) {
            sleep(500);
        }
        
        // 移除监听器
        game.setPlayerActionListener(null);
        
        // 停用玩家卡牌
        SwingUtilities.invokeLater(() -> {
            game.activatePlayerCards(false);
        });
    }
    
    /**
     * 处理电脑玩家回合
     * @param playerIndex 电脑玩家索引
     */
    private void handleComputerPlayerTurn(int playerIndex) {
        // 显示"思考中..."
        SwingUtilities.invokeLater(() -> {
            game.showPlayerStatus(playerIndex, "思考中...");
        });
        
        // 模拟思考时间
        sleep(COMPUTER_THINK_TIME * 1000);
        
        if (!running.get()) return;
        
        // 电脑AI决策
        List<Card> cardsToPlay = game.computerDecision(playerIndex);
        
        if (cardsToPlay != null && !cardsToPlay.isEmpty()) {
            // 电脑出牌
            SwingUtilities.invokeLater(() -> {
                game.playCards(playerIndex, cardsToPlay);
            });
            
            // 显示"出牌"
            game.showPlayerStatus(playerIndex, "出牌");
        } else {
            // 电脑不出
            SwingUtilities.invokeLater(() -> {
                game.passTurn(playerIndex);
            });
            
            // 显示"不要"
            game.showPlayerStatus(playerIndex, "不要");
        }
        
        // 短暂显示状态后清除
        sleep(2000);
        SwingUtilities.invokeLater(() -> {
            game.clearPlayerStatus(playerIndex);
        });
    }
    
    /**
     * 处理游戏结束
     */
    private void handleGameEnd() {
        // 获取获胜方
        int winner = game.getWinner();
        String winnerName;
        
        if (winner == game.getLandlordIndex()) {
            winnerName = "地主";
        } else {
            winnerName = "农民";
        }
        
        // 显示游戏结果
        SwingUtilities.invokeLater(() -> {
            JOptionPane.showMessageDialog(game, 
                winnerName + "获胜！", 
                "游戏结束", 
                JOptionPane.INFORMATION_MESSAGE);
        });
        
        // 等待3秒后回到主界面
        sleep(3000);
        SwingUtilities.invokeLater(() -> {
            game.returnToMainMenu();
        });
    }
    
    /**
     * 启动玩家倒计时
     * @param playerIndex 玩家索引
     * @param duration 倒计时时长（秒）
     */
    private void startPlayerTimer(int playerIndex, int duration) {
        new Thread(() -> {
            for (int i = duration; i >= 0 && running.get(); i--) {
                final int remaining = i;
                SwingUtilities.invokeLater(() -> {
                    game.updateTimerDisplay(playerIndex, remaining);
                });
                
                sleep(1000);
            }
            
            // 倒计时结束
            if (running.get()) {
                SwingUtilities.invokeLater(() -> {
                    game.handleTimeout(playerIndex);
                });
            }
        }).start();
    }
    
    /**
     * 线程休眠辅助方法
     * @param millis 休眠时间（毫秒）
     */
    private void sleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    
    /**
     * 获取当前游戏阶段描述
     * @return 阶段描述
     */
    public String getCurrentPhaseDescription() {
        switch (currentPhase) {
            case PHASE_INIT: return "初始化";
            case PHASE_LANDLORD_SELECTION: return "抢地主阶段";
            case PHASE_GAMEPLAY: return "游戏主阶段";
            default: return "未知阶段";
        }
    }
    
    /**
     * 获取当前玩家索引
     * @return 当前玩家索引（-1表示无）
     */
    public int getCurrentPlayer() {
        return currentPlayer;
    }
    
    /**
     * 获取当前玩家名称
     * @return 玩家名称
     */
    public String getCurrentPlayerName() {
        if (currentPlayer == -1) return "无";
        if (currentPlayer == 1) return "玩家";
        return "电脑" + (currentPlayer == 0 ? "左" : "右");
    }
}